static int CPXPUBLIC
usersetM      (CPXCENVptr   env,
               void         *cbdata,
               int          wherefrom,
               void         *cbhandle,
               int          *useraction_p
	       )   
{
 
   int status = 0;
   int nodecount,seqnum, itercnt=0;
   int rows, cols;
   int i,j,idx,idxR, idxM;
   int mvalidind = 1;
   double coef, objval, bestobjval, bestintval,cutoffval;
   double tol = 0.0000000001;
   char lu[1];
   double bd[1];
   int id[1];
   int depth;
   double   *x   = NULL;
   char nodeLPName[50];
   //   int i_min = 0;
   //   int i_max = 30;
   int cbindIdct = 0;
   int rbindIdct = 0;
   int ybindIdct = 0;
   int      *cstat = NULL;
   int      *rstat = NULL;
   double mingap = -5;


   MINFOptr info = (MINFOptr) cbhandle;   //cast the cbhandle

   /* Read in info of coordinates of big M */
   int *flagPtr = info->flagPtr;
   int ni = info -> ni;
   int nj = info -> nj;
   double stepsize = info->stepsize;
   int **bigmRowIdx = info -> bigmRowIdx;
   int **bigmColIdx = info -> bigmColIdx;
   double *myBestObjValPtr = info -> myBestObjValPtr;
   double ***bigmValsPtr = info -> bigmValsPtr;

   CPXLPptr nodelp;      //Can be modified
   CPXCLPptr lp;         //Constant pointer. Can not be modified
   *flagPtr = 1;

   *useraction_p = CPX_CALLBACK_DEFAULT;

   /* Get pointer to root LP problems */
   status = CPXgetcallbacklp(env, cbdata, wherefrom, &lp);
   if ( status )  goto TERMINATE;

   /* Get pointer to node LP problems */
   status = CPXgetcallbacknodelp (env, cbdata, wherefrom, &nodelp);
   if ( status )  goto TERMINATE;
   //   printf("%d\n", lp);       
   //   printf("%d\n", nodelp);

   /* Find out what nodes is being processed */
   status = CPXgetcallbackinfo (env, cbdata, wherefrom, CPX_CALLBACK_INFO_NODE_COUNT, &nodecount);
   if ( status )  goto TERMINATE;

   /* Find out the node sequential number */
   //   status = CPXgetcallbacknodeinfo( env, cbdata, wherefrom, 0, CPX_CALLBACK_INFO_NODE_SEQNUM, &seqnum);
   if ( status )  goto TERMINATE;
   //   status = CPXgetcallbacknodeinfo( env, cbdata, wherefrom, 0, CPX_CALLBACK_INFO_NODE_DEPTH, &depth);
   if ( status )  goto TERMINATE;
   //   printf("I am at node %d of depth %d \n", seqnum, depth);

   cols = CPXgetnumcols (env, lp);
   if ( cols <= 0 ) {
     fprintf (stdout, "Can't get number of columns.\n");
     status = CPXERR_CALLBACK;
     goto TERMINATE;
   }

   rows = CPXgetnumrows (env, lp);
   if ( rows <= 0 ) {
     fprintf (stdout, "Can't get number of rows.\n");
     status = CPXERR_CALLBACK;
     goto TERMINATE;
   }

   x = (double *) malloc (cols * sizeof (double));
   cstat = (int *) malloc (cols*sizeof(int));
   rstat = (int *) malloc (rows*sizeof(int));

   /* Solve initial node with barrier. others with dual */
   //   status = CPXprimopt(env,nodelp);
   //status = CPXdualopt(env,nodelp);
   if (nodecount < 1)   status = CPXprimopt(env, nodelp);
   else                 status = CPXdualopt(env, nodelp);
   //     status = CPXprimopt(env, nodelp);

   if ( status ) {
     fprintf (stdout, "Can't solve the node LP.");
     goto TERMINATE;
   }

   /* Retrieve the solution at the node LP */
   status = CPXgetx(env, nodelp, x, 0, cols-1);
   if ( status ) {
     fprintf (stdout, "Can't get node solution.");
     goto TERMINATE;
   }

   //      rstat = (int *) malloc (*sizeof(int));
   if ( cstat == NULL ) {
     fprintf (stderr, "No memory for basis statuses.\n");
     goto TERMINATE;
   }
   //      printf("%d\n", cstat);

   status = CPXgetbase (env,  nodelp, cstat, rstat);
   //   printf("%d\n", cstat[5]);
   if ( status ) {
     fprintf (stderr, "Failed to get basis; error %d.\n", status);
     goto TERMINATE;
   }

   status = CPXgetobjval(env, nodelp, &objval);
   if ( status ) {
     fprintf (stdout, "Can't get objective value of node LP.");
     goto TERMINATE;
   }

   //   status = CPXgetcallbackinfo(env, cbdata, wherefrom, CPX_CALLBACK_INFO_USER_PROBLEM, &lp);
   //   status = CPXgetcallbacklp(env, cbdata, wherefrom, &lp);
   //   printf("%d\n", lp);

   // Callback best objective value among the remaing nodes
   //   printf("I am good here!\n");
   status = CPXgetcallbackinfo (env, cbdata, wherefrom,
                                   CPX_CALLBACK_INFO_BEST_REMAINING, &bestobjval);
   if ( status )  goto TERMINATE;
   status = CPXgetcallbackinfo (env, cbdata, wherefrom,
                                   CPX_CALLBACK_INFO_BEST_INTEGER, &bestintval);
   if ( status )  goto TERMINATE;
   status = CPXgetcallbackinfo (env, cbdata, wherefrom,
                                   CPX_CALLBACK_INFO_CUTOFF, &cutoffval);
   if ( status )  goto TERMINATE;






   if(objval >0 && objval < *myBestObjValPtr)
     *myBestObjValPtr = objval;

   for(i = 0; i< ni; i++){
     for(j = 0; j< nj; j++){

       idx = (ni + nj*i + (j+1)) - ni; // index of x at the solution vector    /why this is correct?
       idxR = (ni+1)*nj + i+1;         // index of y(b) at the solution vector /why this is correct?

       status = CPXgetcoef(env, lp, bigmRowIdx[i][j], bigmColIdx[i][j], &coef);
       if(status == 1){
	 printf("I have something wrong here!\n");
	 goto TERMINATE;
       }
       
       rbindIdct = rstat[bigmRowIdx[i][j]];
       cbindIdct = cstat[idx];
       ybindIdct = cstat[idxR];

       // Big M Checking routine
       // Binding
      if( coef + 1.0 <= tol || cstat[idx] == CPX_FREE_SUPER ||rbindIdct == CPX_BASIC) {
	//x[idx] <= tol
	 itercnt ++; 
	 //	 printf("%f %f %d %f\n", coef+1.0, x[idx], rbindIdct, x[idx] + coef*x[idxR]);
	 //	 if(mingap <= x[idx] + coef*x[idxR]) mingap = x[idx] + coef*x[idxR];
	 continue;
       }
      // Unbinding
       else{
	 if(coef - stepsize >= -1.0) coef = coef - stepsize;
	 else coef = -1.0;

	 (*bigmValsPtr)[i][j] = coef;
       }
     }
   }
  // End of checking loop

   //   printf("itercnt is %d status is %d\n", itercnt, status);

  if (itercnt == ni*nj){
     *useraction_p = CPX_CALLBACK_SET;
     //     printf("%f %f %f %f\n", bestobjval, bestintval, cutoffval, mingap);
     goto TERMINATE;
   }
  else{//Go to the next iteration
    //    printf(" Go to the next iteration! \n");
    //fprintf(logfile, "Best lower bound is %12.6f \n", cutoffval);
    free_and_null ((char **) &x);
    *flagPtr = 0;
    *useraction_p = CPX_CALLBACK_FAIL;   //Stop the mipopt
    goto TERMINATE;
    //     return 1;
  }

  //   *useraction_p = CPX_CALLBACK_DEFAULT;
   *useraction_p = CPX_CALLBACK_SET;

 TERMINATE:

   free_and_null ((char **) &x);
   free_and_null ((char **) &rstat);
   free_and_null ((char **) &cstat);
   return (status);

}   //End of callback function usersetM
